home *** CD-ROM | disk | FTP | other *** search
- /*
- * mountd This program handles RPC "NFS" mount requests.
- *
- * Usage: [rpc.]mountd [-dhnpv] [-f authfile]
- *
- * Authors: Mark A. Shand, May 1988
- * Donald J. Becker, <becker@super.org>
- * Rick Sladkey, <jrs@world.std.com>
- * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
- * Olaf Kirch, <okir@monad.swb.de>
- *
- * Copyright 1988 Mark A. Shand
- * This software maybe be used for any purpose provided
- * the above copyright notice is retained. It is supplied
- * as is, with no warranty expressed or implied.
- */
-
- /*
-
- WANT_LOG_MOUNTS guarded patch is added Aug 18, 1995 by Alex Yuriev
- (alex@bach.cis.temple.edu), CIS Laboratories,
- TEMPLE UNIVERSITY, USA
-
- This version is ugly and can be really improved but it actually
- pinpointed a couple of intruders :)
-
- */
-
-
- #include "mountd.h"
- #include "getopt.h"
- #include "rpcmisc.h"
- #include "rmtab.h"
-
-
- static _PRO(void usage, (FILE *, int) );
-
- static struct option longopts[] =
- {
- { "debug", 0, 0, 'd' },
- { "exports-file", 1, 0, 'f' },
- { "help", 0, 0, 'h' },
- { "allow-non-root", 0, 0, 'n' },
- { "promiscous", 0, 0, 'p' },
- { "re-export", 0, 0, 'r', },
- { "version", 0, 0, 'v' },
- { NULL, 0, 0, 0 }
- };
-
- char argbuf[MNTPATHLEN + 1];
- char *auth_file = NULL;
- static char *program_name;
- int need_reinit = 0;
- int need_flush = 0;
- extern char version[];
-
- /* The NULL request handler. */
- void *mountproc_null_1_svc(argp, rqstp)
- void *argp;
- struct svc_req *rqstp;
- {
- return ((void *) &result);
- }
-
- fhstatus *mountproc_mnt_1_svc(argp, rqstp)
- dirpath *argp;
- struct svc_req *rqstp;
- {
- static fhstatus *res;
- struct stat stbuf;
- nfs_client *cp;
- nfs_mount *mp;
- char nargbuf[MNTPATHLEN + 1];
- #ifdef WANT_LOG_MOUNTS
- struct in_addr addr;
- #endif /* WANT_LOG_MOUNTS */
-
- res = (struct fhstatus *)&result;
-
- if (**argp == '\0') {
- strcpy(argbuf, "/");
- } else {
- /* don't trust librpc */
- strncpy(argbuf, *argp, MNTPATHLEN);
- argbuf[MNTPATHLEN] = '\0';
- }
-
- /* It is important to resolve symlinks before checking permissions. */
- if (realpath(argbuf, nargbuf) == NULL) {
- res->fhs_status = nfs_errno();
- dprintf (D_CALL, "\tmount res = %d\n", res->fhs_status);
- return (res);
- }
- strcpy(argbuf, nargbuf);
-
- #ifdef WANT_LOG_MOUNTS
- addr = svc_getcaller(rqstp->rq_xprt)->sin_addr;
- dprintf(L_NOTICE, "NFS mount of %s attempted from %s\n",
- argbuf, inet_ntoa(addr));
- #endif /* WANT_LOG_MOUNTS */
-
- if (stat(argbuf, &stbuf) < 0) {
- res->fhs_status = nfs_errno();
- dprintf (D_CALL, "\tmount res = %d\n", res->fhs_status);
- return (res);
- }
-
- /* Now authenticate the intruder... */
- if (((cp = auth_clnt(rqstp)) == NULL)
- || (mp = auth_path(cp, rqstp, argbuf)) == NULL
- || mp->o.noaccess) {
- res->fhs_status = NFSERR_ACCES;
- #ifdef WANT_LOG_MOUNTS
- dprintf(L_WARNING, "Blocked attempt of %s to mount %s\n",
- inet_ntoa(addr), argbuf);
- #endif /* WANT_LOG_MOUNTS */
- } else if (!S_ISDIR(stbuf.st_mode) && !S_ISREG(stbuf.st_mode)) {
- res->fhs_status = NFSERR_NOTDIR;
- } else if (!re_export && nfsmounted(argbuf, &stbuf)) {
- res->fhs_status = NFSERR_ACCES;
- } else {
- res->fhs_status = fh_create((nfs_fh *)
- &(res->fhstatus_u.fhs_fhandle), argbuf);
- rmtab_add_client(argbuf, rqstp);
- #ifdef WANT_LOG_MOUNTS
- dprintf(L_NOTICE, "%s has been mounted by %s\n",
- argbuf, inet_ntoa(addr));
- #endif /* WANT_LOG_MOUNTS */
- }
- dprintf (D_CALL, "\tmount res = %d\n", res->fhs_status);
- return (res);
- }
-
- mountlist *mountproc_dump_1_svc(argp, rqstp)
- void *argp;
- struct svc_req *rqstp;
- {
- return (rmtab_lst_client());
- }
-
- void *mountproc_umnt_1_svc(argp, rqstp)
- dirpath *argp;
- struct svc_req *rqstp;
- {
- rmtab_del_client(*argp, rqstp);
- return ((void*) &result);
- }
-
- void *mountproc_umntall_1_svc(argp, rqstp)
- void *argp;
- struct svc_req *rqstp;
- {
- rmtab_mdel_client(rqstp);
- return ((void*) &result);
- }
-
- exports *mountproc_export_1_svc(argp, rqstp)
- void *argp;
- struct svc_req *rqstp;
- {
- return (&export_list);
- }
-
- exports *mountproc_exportall_1_svc(argp, rqstp)
- void *argp;
- struct svc_req *rqstp;
- {
- return (&export_list);
- }
-
- int main(argc, argv)
- int argc;
- char *argv[];
- {
- int foreground = 0;
- int c;
-
- rpc_init("mountd", MOUNTPROG, MOUNTVERS, mount_dispatch, 0, 0);
-
- program_name = argv[0];
-
- /* Parse the command line options and arguments. */
- opterr = 0;
- while ((c = getopt_long(argc, argv, "Fd:f:hnprv", longopts, NULL)) != EOF)
- switch (c) {
- case 'F':
- foreground = 1;
- break;
- case 'h':
- usage(stdout, 0);
- break;
- case 'd':
- enable_logging(optarg);
- break;
- case 'f':
- auth_file = optarg;
- break;
- case 'n':
- allow_non_root = 1;
- break;
- case 'p':
- promiscuous = 1;
- break;
- case 'r':
- re_export = 1;
- break;
- case 'v':
- printf("%s\n", version);
- exit(0);
- case 0:
- break;
- case '?':
- default:
- usage(stderr, 1);
- }
-
- /* No more arguments allowed. */
- if (optind != argc)
- usage(stderr, 1);
-
- if (_rpcpmstart)
- foreground = 1;
-
- if (!foreground) {
- #ifndef RPC_SVC_FG
- /* We first fork off a child. */
- if ((c = fork()) > 0)
- exit(0);
- if (c < 0) {
- fprintf(stderr, "mountd: cannot fork: %s\n",
- strerror(errno));
- exit(-1);
- }
- /* Now we remove ourselves from the foreground. */
- (void) close(0);
- (void) close(1);
- (void) close(2);
- #ifdef TIOCNOTTY
- if ((c = open("/dev/tty", O_RDWR)) >= 0) {
- (void) ioctl(c, TIOCNOTTY, (char *) NULL);
- (void) close(c);
- }
- #else
- setsid();
- #endif
- #endif /* not RPC_SVC_FG */
- }
-
- /* Initialize logging. */
- log_open("mountd", foreground);
-
- /* Initialize the FH module. */
- fh_init();
-
- /* Initialize the AUTH module. */
- auth_init(auth_file);
-
- /* Enable the LOG toggle with a signal. */
- (void) signal(SIGUSR1, toggle_logging);
-
- /* Enable rereading of exports file */
- (void) signal(SIGHUP, reinitialize);
-
- svc_run ();
-
- dprintf (L_ERROR, "Ack! Gack! svc_run returned!\n");
- exit (1);
- }
-
- static void usage(fp, n)
- FILE *fp;
- int n;
- {
- fprintf(fp, "Usage: %s [-Fhnpv] [-d kind] [-f exports-file]\n",
- program_name);
- fprintf(fp, " [--debug kind] [--help] [--allow-non-root]\n");
- fprintf(fp, " [--promiscuous] [--version]\n");
- fprintf(fp, " [--exports-file=file]\n");
- exit(n);
- }
-
- RETSIGTYPE reinitialize(int sig)
- {
- static volatile int inprogress = 0;
-
- signal (SIGHUP, reinitialize);
- if (_rpcsvcdirty) {
- need_reinit = 1;
- return;
- }
- if (inprogress++)
- return;
- fh_flush(1);
- auth_init(NULL);
- inprogress = 0;
- need_reinit = 0;
- }
-
- /*
- * Don't look. This is an awful hack to overcome a link problem with
- * auth_clnt temporarily.
- */
- uid_t luid(uid, mp, rqstp)
- uid_t uid;
- nfs_mount *mp;
- struct svc_req *rqstp;
- {
- return -2;
- }
-
- gid_t lgid(gid, mp, rqstp)
- gid_t gid;
- nfs_mount *mp;
- struct svc_req *rqstp;
- {
- return -2;
- }
-
- void
- ugid_free_map(map)
- struct ugid_map *map;
- {
- /* NOP */
- }
-
- void
- ugid_map_uid(mp, from, to)
- nfs_mount *mp;
- uid_t from;
- uid_t to;
- {
- /* NOP */
- }
-
- void
- ugid_map_gid(mp, from, to)
- nfs_mount *mp;
- gid_t from;
- gid_t to;
- {
- /* NOP */
- }
-